package com.smzd.utils.httpclient;

import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.http.HttpEntity;
import org.apache.http.NameValuePair;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.entity.mime.MultipartEntity;
import org.apache.http.entity.mime.content.FileBody;
import org.apache.http.entity.mime.content.StringBody;
import org.apache.http.message.BasicNameValuePair;

import com.smzd.utils.FileUtil;

public class Request {
	public static final int METHOD_GET = 0;
	public static final int METHOD_POST = 1;

	private Client client;
	private String url;
	private int method = 0;
	private String encoding = "UTF-8";
	private List<NameValuePair> params = null;
	private Map<String, String> headers = null;
	private Map<String, File> files;

	public Request() {
	}

	public Request(String url) {
		this.url = url;
	}

	public Request(int method) {
		this.method = method;
	}

	public Request(String url, int method) {
		this.url = url;
		this.method = method;
	}

	public Response execute() throws Exception {
		return client.operate(this);
	}

	public Response executeWithRedirect() throws Exception {
		return client.operateWithRedirect(this);
	}

	public HttpUriRequest getHttpRequest() throws Exception {
		HttpUriRequest request;
		HttpEntity entity = null;
		if (method == METHOD_POST && files != null && files.size() > 0) {
			MultipartEntity me = new MultipartEntity();
			for (String name : files.keySet()) {
				File file = files.get(name);
				FileBody fb = new FileBody(file);
				me.addPart(name, fb);
			}
			if (params != null && params.size() > 0) {
				for (NameValuePair nvp : params) {
					StringBody sb = new StringBody(nvp.getValue());
					me.addPart(nvp.getName(), sb);
				}
			}
			entity = me;
		} else if (params != null) {
			entity = new UrlEncodedFormEntity(params, encoding);
		}
		if (method == METHOD_GET) {
			String thisUrl;
			if (entity != null) {
				StringBuffer sb = FileUtil.readContent(entity.getContent());
				if (url.indexOf("?") > 0) {
					sb.insert(0, "&");
				} else {
					sb.insert(0, "?");
				}
				sb.insert(0, url);
				thisUrl = sb.toString();
			} else {
				thisUrl = url;
			}
			request = new HttpGet(thisUrl);
		} else if (method == METHOD_POST) {
			HttpPost post = new HttpPost(url);
			if (entity != null) {
				post.setEntity(entity);
			}
			request = post;
		} else {
			throw new Exception("Unsupported method! method=" + method);
		}
		initHeaders();
		addHeaders(request);
		return request;
	}

	private void addHeaders(HttpUriRequest req) {
		if (headers != null && headers.size() > 0) {
			for (String key : headers.keySet()) {
				String value = headers.get(key);
				req.addHeader(key, value);
			}
		}
	}

	private void initHeaders() {
		addHeader(
				"User-Agent",
				"Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN; rv:1.9.2.6) Gecko/20100625 Firefox/3.6.6 Greatwqs");
		// addHeader("Accept","text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8");
		addHeader("Accept-Language", "zh-cn,zh;q=0.5");
		addHeader("Accept-Charset", "ISO-8859-1,utf-8,gb2312,gbk;q=0.7,*;q=0.7");
		// httpRequest.addHeader("X-Real-IP", "1.1.1.1");
		// httpRequest.addHeader("Proxy-Client-IP", "1.1.1.1");
		// httpRequest.addHeader("X-Forward-For", "1.1.1.1");

	}

	public Request addParameter(String name, String value) {
		NameValuePair nv = new BasicNameValuePair(name, value);
		if (this.params == null) {
			this.params = new ArrayList<NameValuePair>();
		}
		this.params.add(nv);
		return this;
	}

	public int getMethod() {
		return method;
	}

	public String getEncoding() {
		return encoding;
	}

	public void setMethod(int method) {
		this.method = method;
	}

	public void setEncoding(String encoding) {
		this.encoding = encoding;
	}

	public List<NameValuePair> getParams() {
		return params;
	}

	public void setParams(List<NameValuePair> params) {
		this.params = params;
	}

	public String getUrl() {
		return url;
	}

	public void setUrl(String url) {
		this.url = url;
	}

	public Client getClient() {
		return client;
	}

	void setClient(Client client) {
		this.client = client;
	}

	public Request addHeader(String name, String value) {
		if (headers == null) {
			headers = new HashMap<String, String>();
		}
		headers.put(name, value);
		return this;
	}

	public Request addFile(String name, File file) {
		if (files == null) {
			files = new HashMap<String, File>();
		}
		files.put(name, file);
		return this;
	}
}
